/* useFileChunk hooks 负责人 zhukai */

import type { FileChunk, Message } from "./type"

const DEFAULT_CHUNK_SIZE = 1024 * 1024 * 2 // 2MB
let THREAD_COUNT = navigator.hardwareConcurrency || 4 // 暂定线程数量
export function useFileChunk(FILE: File, CHUNK_SIZE = DEFAULT_CHUNK_SIZE) {
  const chunkCount = Math.ceil(FILE.size / CHUNK_SIZE) // 文件块的数量

  let finshedThread = 0 //  已经完成的线程数量

  async function sliceFile() {
    return new Promise<FileChunk[]>((resolve) => {
      const chunks: FileChunk[] = []
      // 计算线程要处理的文件块数量
      const chunksForEachThread = Math.ceil(chunkCount / THREAD_COUNT)
      let currentChunkCount = 0
      // 通知线程需要处理哪些文件块
      for (let i = 0; i < THREAD_COUNT; i++) {
        const worker = new Worker(
          new URL("./worker", import.meta.url), // 这里必须要使用这个写法，否则vite不会把这个文件当作模块引入
          { type: "module" }
        )
        const message = {
          FILE,
          CHUNK_SIZE,
          start: i * chunksForEachThread,
          end: Math.min((i + 1) * chunksForEachThread, chunkCount)
        } as Message
        worker.postMessage(message)
        worker.onmessage = (e) => {
          const res = e.data
          for (let i = 0; i < res.length; i++) chunks[res[i].index] = res[i]
          // 关闭线程
          worker.terminate()
          // 当所有线程都完成时，返回文件块数组
          finshedThread++
          if (finshedThread === THREAD_COUNT) resolve(chunks)
        }
        // 如果当前线程处理的文件块数量大于总文件块数量，说明已经没有文件块需要处理了，可以退出循环。
        // 并且将线程数量设置为当前线程数量
        currentChunkCount += chunksForEachThread
        if (currentChunkCount > chunkCount) {
          THREAD_COUNT = i + 1
          break
        }
      }
    })
  }

  return {
    sliceFile
  }
}
